#pragma once
#include <string>
#include <vector>
#include <map>
#include "SQLCommon.h"
#include "DBPageManager.h"
#include "TableInfo.h"
#include "RowStructure.h"

struct SQLPage
{
	DB_PGHEADER pgheader;
	char pgdata[DB_PGSIZE - 4];
	short slots;
	short slotNum;
};

class Slot
{
private:
	friend bool operator < (const Slot & lhs, const Slot & rhs);
	friend class SQLTable;
	short slotNum, offset;
public:
	Slot(short num, short off) : slotNum(num), offset(off) {}

};

bool operator < (const Slot & lhs, const Slot & rhs);

class SQLTable
{
private:
	std::string tableName;
	int fd;
	TABLE_INFO * tableInfo;
public:
	class Iterator
	{
	private:
		friend class SQLTable;
		int pageId, slotId;
	public:
		Iterator() : pageId(0), slotId(0) {}
		Iterator(int pId, int sId) : pageId(pId), slotId(sId) {}
		void SetRid(int pId, int sId) { pageId = pId; slotId = sId; }
	};
	SQLTable(void);
	SQLTable(std::string name) : tableName(name), fd(-1), tableInfo(NULL) {}
	int OpenTable();
	int AllocatePage(int fileid, int* pageid, DB_PAGE ** buf);
	int GetPage(int fileid, int pageid, DB_PAGE ** buf);
	int CreateTable(std::string tableName);
	int Flush();
	int CloseTable();
	Iterator & InsertRecord(int size, char * data);
	int GetRecord(Iterator & rId, RowStructure & row);
	bool GetNextRecord(Iterator & rId, std::map<std::string,std::string> & result);
	Iterator GetFirstRid() { return Iterator(tableInfo->firstPageId, -1); }
	int Defragmentation(int pId);
	int SelectAllRecord(std::vector<std::map<std::string,std::string>> & rowSet);
	int DeleteRecord(const Iterator & rId);
	~SQLTable(void);
private:
	Iterator start, end, newSlot;
};
